﻿using System.Collections.Generic;
using System.Collections.Specialized;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Web.Mvc.Html;
using System.Web.Routing;

namespace System.Web.Mvc
{
    public static class HtmlHelperExtension
    {
        /// <summary>
        /// 显示弹出框
        /// </summary>
        /// <typeparam name="TModel">模型</typeparam>
        /// <typeparam name="TProperty">属性</typeparam>
        /// <param name="html">HtmlHelper</param>
        /// <param name="expression">要显示的属性</param>
        /// <param name="displayLength">显示长度</param>
        /// <returns></returns>
        public static MvcHtmlString PopoverFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, int displayLength)
        {
            var modelMetadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
            string content = null != modelMetadata.Model ? modelMetadata.Model.ToString() : string.Empty;
            TagBuilder tb = new TagBuilder("div");
            tb.MergeAttribute("title", content);
            var text = content.Length > displayLength ? (content.Substring(0, displayLength) + "...") : content;
            tb.SetInnerText(text);
            return MvcHtmlString.Create(tb.ToString());
        }

        /// <summary>
        /// 字符串截取
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="html"></param>
        /// <param name="expression"></param>
        /// <param name="startIndex">开始索引</param>
        /// <param name="length">显示长度</param>
        /// <returns></returns>
        public static MvcHtmlString SubstringFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, int startIndex, int length)
        {
            var modelMetadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
            string content = modelMetadata.Model as string ?? string.Empty;
            TagBuilder tb = new TagBuilder("div");
            tb.MergeAttribute("style", "padding:5px;");
            tb.MergeAttribute("title", content);
            if (!string.IsNullOrEmpty(content))
            {
                int start = Math.Min(Math.Abs(startIndex), content.Length - 1);
                if (content.Length > length + 3)
                {
                    content = content.Substring(start, length) + "…";
                }
                tb.SetInnerText(content);
            }
            return MvcHtmlString.Create(tb.ToString());
        }

        /// <summary>
        /// 生成Img标签
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="html"></param>
        /// <param name="expression"></param>
        /// <param name="htmlAttributes">Html属性</param>
        /// <returns></returns>
        public static MvcHtmlString ImageFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, object htmlAttributes)
        {
            var modelMetadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
            string url = (null != modelMetadata.Model && !string.IsNullOrEmpty(modelMetadata.Model.ToString())) ? modelMetadata.Model.ToString() : "/Images/none.gif";
            TagBuilder tb = new TagBuilder("img");
            tb.MergeAttribute("src", url);
            tb.MergeAttribute("alt", "无图片");
            tb.MergeAttribute("name", modelMetadata.PropertyName);
            if (null != htmlAttributes)
            {
                var properties = htmlAttributes.GetType().GetProperties().ToList();
                properties.ForEach(p => tb.MergeAttribute(p.Name, p.GetValue(htmlAttributes).ToString()));
            }
            return MvcHtmlString.Create(tb.ToString(TagRenderMode.SelfClosing));
        }
        public static MvcHtmlString ImageFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, Dictionary<string, object> htmlAttributes)
        {
            var modelMetadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
            string url = (null != modelMetadata.Model && !string.IsNullOrEmpty(modelMetadata.Model.ToString())) ? modelMetadata.Model.ToString() : "/Images/none.gif";
            TagBuilder tb = new TagBuilder("img");
            tb.MergeAttribute("src", url);
            tb.MergeAttribute("alt", modelMetadata.DisplayName);
            tb.MergeAttribute("name", modelMetadata.PropertyName);
            if (null != htmlAttributes)
            {
                foreach (var key in htmlAttributes.Keys)
                {
                    tb.MergeAttribute(key, htmlAttributes[key].ToString());
                }
            }
            return MvcHtmlString.Create(tb.ToString(TagRenderMode.SelfClosing));
        }

        /// <summary>
        /// 使用byte[]生成Img标签
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="html"></param>
        /// <param name="expression"></param>
        /// <param name="htmlAttributes">Html属性</param>
        /// <returns></returns>
        public static MvcHtmlString ImageContentFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null, string noImageUrl = null)
        {
            Dictionary<string, object> htmlAttr = new Dictionary<string, object>();
            if (null != htmlAttributes)
            {
                var properties = htmlAttributes.GetType().GetProperties().ToList();
                properties.ForEach(p => htmlAttr.Add(p.Name, p.GetValue(htmlAttributes).ToString()));
            }
            return ImageContentFor(html, expression, htmlAttr, noImageUrl: noImageUrl);
        }
        /// <summary>
        /// 使用byte[]生成Img标签
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="html"></param>
        /// <param name="expression"></param>
        /// <param name="htmlAttributes">Html属性</param>
        /// <param name="noImageUrl">无图时的替代图片路径</param>
        /// <returns></returns>
        public static MvcHtmlString ImageContentFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes, string noImageUrl = null)
        {
            var modelMetadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
            string url = null;
            if (modelMetadata.Model != null)
            {
                byte[] data = (byte[])modelMetadata.Model;
                url = "data:image/jpg;base64," + Convert.ToBase64String(data);
            }
            else
            {
                if (string.IsNullOrEmpty(noImageUrl))
                    url = "/Content/images/noimage.png";
                else
                    url = noImageUrl;
            }
            TagBuilder tb = new TagBuilder("img");
            tb.MergeAttribute("src", url);
            tb.MergeAttribute("alt", modelMetadata.DisplayName);
            tb.MergeAttribute("name", modelMetadata.PropertyName);
            //暂时不定义Id,到使用时如果需要，通过htmlAttribute设置
            //tb.MergeAttribute("id", modelMetadata.PropertyName);
            if (null != htmlAttributes)
            {
                foreach (string key in htmlAttributes.Keys)
                {
                    tb.MergeAttribute(key, htmlAttributes[key].ToString());
                }
            }
            return MvcHtmlString.Create(tb.ToString(TagRenderMode.SelfClosing));
        }
        /// <summary>
        /// 使用byte[]生成Img标签
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="html"></param>
        /// <param name="expression"></param>
        /// <param name="expression">限制图片最大宽度</param>
        /// <param name="htmlAttributes">Html属性</param>
        /// <returns></returns>
        public static MvcHtmlString ImageContentLimitWidthFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, int maxWidth = 300, object htmlAttributes = null, string noImageUrl = null)
        {
            Dictionary<string, object> htmlAttr = new Dictionary<string, object>();
            if (null != htmlAttributes)
            {
                var properties = htmlAttributes.GetType().GetProperties().ToList();
                properties.ForEach(p => htmlAttr.Add(p.Name, p.GetValue(htmlAttributes).ToString()));
            }
            return ImageContentLimitWidthFor(html, expression, maxWidth, htmlAttr, noImageUrl: noImageUrl);
        }
        /// <summary>
        /// 使用byte[]生成Img标签
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="html"></param>
        /// <param name="expression">限制图片最大宽度</param>
        /// <param name="maxWidth"></param>
        /// <param name="htmlAttributes">Html属性</param>
        /// <param name="noImageUrl">无图时的替代图片路径</param>
        /// <returns></returns>
        public static MvcHtmlString ImageContentLimitWidthFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, int maxWidth = 300, IDictionary<string, object> htmlAttributes = null, string noImageUrl = null)
        {
            var modelMetadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
            string url = null;
            if (modelMetadata.Model != null)
            {
                byte[] data = (byte[])modelMetadata.Model;
                MemoryStream stream = new MemoryStream(data);
                Image image = Image.FromStream(stream);
                if (image.Width > maxWidth)
                {
                    Image bitmap = new Bitmap(image, new SizeF(maxWidth, image.Height * (maxWidth / (float)image.Width)).ToSize());
                    MemoryStream streamOut = new MemoryStream();
                    bitmap.Save(streamOut, Drawing.Imaging.ImageFormat.Png);
                    url = "data:image/jpg;base64," + Convert.ToBase64String(streamOut.GetBuffer());
                }
                else
                    url = "data:image/jpg;base64," + Convert.ToBase64String(data);
            }
            else
            {
                if (string.IsNullOrEmpty(noImageUrl))
                    url = "/Content/images/noimage.png";
                else
                    url = noImageUrl;
            }
            TagBuilder tb = new TagBuilder("img");
            tb.MergeAttribute("src", url);
            tb.MergeAttribute("alt", modelMetadata.DisplayName);
            tb.MergeAttribute("name", modelMetadata.PropertyName);
            //暂时不定义Id,到使用时如果需要，通过htmlAttribute设置
            //tb.MergeAttribute("id", modelMetadata.PropertyName);
            if (null != htmlAttributes)
            {
                foreach (string key in htmlAttributes.Keys)
                {
                    tb.MergeAttribute(key, htmlAttributes[key].ToString());
                }
            }
            return MvcHtmlString.Create(tb.ToString(TagRenderMode.SelfClosing));
        }
        public static MvcHtmlString ImageContent(this HtmlHelper html, byte[] data, object htmlAttributes = null, string noImageUrl = null)
        {
            Dictionary<string, object> htmlAttr = new Dictionary<string, object>();
            if (null != htmlAttributes)
            {
                var properties = htmlAttributes.GetType().GetProperties().ToList();
                properties.ForEach(p => htmlAttr.Add(p.Name, p.GetValue(htmlAttributes).ToString()));
            }
            return ImageContent(html, data, htmlAttr, noImageUrl: noImageUrl);
        }

        public static MvcHtmlString ImageContent(this HtmlHelper html, byte[] data, IDictionary<string, object> htmlAttributes)
        {
            string url = null;
            url = "data:image/jpg;base64," + Convert.ToBase64String(data);
            TagBuilder tb = new TagBuilder("img");
            tb.MergeAttribute("src", url);
            //暂时不定义Id,到使用时如果需要，通过htmlAttribute设置
            //tb.MergeAttribute("id", modelMetadata.PropertyName);
            if (null != htmlAttributes)
            {
                foreach (string key in htmlAttributes.Keys)
                {
                    tb.MergeAttribute(key, htmlAttributes[key].ToString());
                }
            }
            return MvcHtmlString.Create(tb.ToString(TagRenderMode.SelfClosing));
        }
        /// <summary>
        /// 生成具有预览功能的图片标签
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="html"></param>
        /// <param name="expression"></param>
        /// <param name="htmlAttributes"></param>
        /// <returns></returns>
        public static MvcHtmlString LightboxFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, object htmlAttributes, string lightbox = "preview")
        {
            var modelMetadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
            string url = (null != modelMetadata.Model && !string.IsNullOrEmpty(modelMetadata.Model.ToString())) ? modelMetadata.Model.ToString() : "/Images/none.gif";
            TagBuilder tbImg = new TagBuilder("img");
            tbImg.MergeAttribute("src", url);
            tbImg.MergeAttribute("alt", modelMetadata.DisplayName);
            tbImg.MergeAttribute("name", modelMetadata.PropertyName);
            if (null != htmlAttributes)
            {
                var properties = htmlAttributes.GetType().GetProperties().ToList();
                properties.ForEach(p => tbImg.MergeAttribute(p.Name, p.GetValue(htmlAttributes).ToString()));
            }
            TagBuilder tbA = new TagBuilder("a");
            tbA.MergeAttribute("href", url);
            tbA.MergeAttribute("title", "点击查看大图");
            tbA.MergeAttribute("data-lightbox", lightbox);
            tbA.InnerHtml = tbImg.ToString(TagRenderMode.SelfClosing);
            return MvcHtmlString.Create(tbA.ToString());
        }

        /// <summary>
        /// 生成file标签
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="html"></param>
        /// <param name="expression"></param>
        /// <param name="htmlAttributes"></param>
        /// <returns></returns>
        public static MvcHtmlString FileFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null)
        {
            Dictionary<string, object> htmlAttr = new Dictionary<string, object>();
            if (null != htmlAttributes)
            {
                var properties = htmlAttributes.GetType().GetProperties().ToList();
                properties.ForEach(p => htmlAttr.Add(p.Name, p.GetValue(htmlAttributes).ToString()));
            }
            return FileFor(html, expression, htmlAttr);
        }

        /// <summary>
        /// 生成file标签
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="html"></param>
        /// <param name="expression"></param>
        /// <param name="htmlAttributes"></param>
        /// <returns></returns>
        public static MvcHtmlString FileFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes)
        {
            var modelMetadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
            TagBuilder tb = new TagBuilder("input");
            tb.MergeAttribute("type", "file");
            //由于属性无法直接接受文件数据，因此在后面加上后缀
            tb.MergeAttribute("name", modelMetadata.PropertyName);// + "_" + Guid.NewGuid().ToString());
            if (!htmlAttributes.Keys.Contains("class"))
                tb.MergeAttribute("class", "form-control");
            if (null != htmlAttributes)
            {
                foreach (string key in htmlAttributes.Keys)
                {
                    tb.MergeAttribute(key, htmlAttributes[key].ToString());
                }
            }
            return MvcHtmlString.Create(tb.ToString());
        }
        public static MvcHtmlString File<TModel>(this HtmlHelper<TModel> html, string expression, object htmlAttributes = null)
        {
            Dictionary<string, object> htmlAttr = new Dictionary<string, object>();
            if (null != htmlAttributes)
            {
                var properties = htmlAttributes.GetType().GetProperties().ToList();
                properties.ForEach(p => htmlAttr.Add(p.Name, p.GetValue(htmlAttributes).ToString()));
            }
            return File(html, expression, htmlAttr);
        }
        public static MvcHtmlString File<TModel>(this HtmlHelper<TModel> html, string expression, IDictionary<string, object> htmlAttributes)
        {
            TagBuilder tb = new TagBuilder("input");
            tb.MergeAttribute("type", "file");
            //由于属性无法直接接受文件数据，因此在后面加上后缀
            tb.MergeAttribute("name", expression);// + "_" + Guid.NewGuid().ToString());
            if (!htmlAttributes.Keys.Contains("class"))
                tb.MergeAttribute("class", "form-control");
            if (null != htmlAttributes)
            {
                foreach (string key in htmlAttributes.Keys)
                {
                    tb.MergeAttribute(key, htmlAttributes[key].ToString());
                }
            }
            return MvcHtmlString.Create(tb.ToString());
        }


    }

    /// <summary>
    /// 分页
    /// </summary>
    public static class PagerHelper
    {
        /// <summary>
        /// 无记录时分页显示方式
        /// </summary>
        /// <returns></returns>
        public static MvcHtmlString EmptyPager()
        {
            return MvcHtmlString.Create("");
        }
        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="currentPageIndex">当前页</param>
        /// <param name="pageSize">分页尺寸</param>
        /// <param name="recordCount">记录总数</param>
        /// <param name="htmlAttributes">分页头标签属性</param>
        /// <param name="className">分页样式</param>
        /// <param name="mode">分页模式</param>
        /// <returns></returns>
        public static MvcHtmlString Pager(this HtmlHelper helper, int currentPageIndex, int pageSize, int recordCount, object htmlAttributes, string className, PageMode mode)
        {
            if (recordCount == 0) return EmptyPager();
            //TagBuilder tbDiv = new TagBuilder("div");
            //tbDiv.AddCssClass("pagination pagination-centered");
            //tbDiv.AddCssClass(className);
            TagBuilder tbUl = new TagBuilder("ul");
            tbUl.AddCssClass("pagination");
            tbUl.IdAttributeDotReplacement = "_";
            tbUl.GenerateId(string.Format("id_{0}", Guid.NewGuid().ToString()));
            tbUl.MergeAttributes(new RouteValueDictionary(htmlAttributes));
            tbUl.InnerHtml = GetNormalPage(helper, currentPageIndex, pageSize, recordCount, mode).ToHtmlString();
            //tbDiv.InnerHtml = tbUl.ToString();
            //return MvcHtmlString.Create(tbDiv.ToString());
            return MvcHtmlString.Create(tbUl.ToString());
        }

        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="currentPageIndex">当前页</param>
        /// <param name="pageSize">分页尺寸</param>
        /// <param name="recordCount">记录总数</param>
        /// <param name="className">分页样式</param>
        /// <returns></returns>
        public static MvcHtmlString Pager(this HtmlHelper helper, int currentPageIndex, int pageSize, int recordCount, string className)
        {
            return Pager(helper, currentPageIndex, pageSize, recordCount, null, className, PageMode.Normal);
        }
        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="currentPageIndex">当前页</param>
        /// <param name="pageSize">分页尺寸</param>
        /// <param name="recordCount">记录总数</param>
        /// <returns></returns>
        public static MvcHtmlString Pager(this HtmlHelper helper, int currentPageIndex, int pageSize, int recordCount)
        {
            return Pager(helper, currentPageIndex, pageSize, recordCount, null);
        }
        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="currentPageIndex">当前页</param>
        /// <param name="pageSize">分页尺寸</param>
        /// <param name="recordCount">记录总数</param>
        /// <param name="mode">分页模式</param>
        /// <returns></returns>
        public static MvcHtmlString Pager(this HtmlHelper helper, int currentPageIndex, int pageSize, int recordCount, PageMode mode)
        {
            return Pager(helper, currentPageIndex, pageSize, recordCount, null, mode);
        }

        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="currentPageIndex">当前页</param>
        /// <param name="pageSize">分页尺寸</param>
        /// <param name="recordCount">记录总数</param>
        /// <param name="className">分页样式</param>
        /// <param name="mode">分页模式</param>
        /// <returns></returns>
        public static MvcHtmlString Pager(this HtmlHelper helper, int currentPageIndex, int pageSize, int recordCount, string className, PageMode mode)
        {
            return Pager(helper, currentPageIndex, pageSize, recordCount, null, className, mode);
        }

        /// <summary>
        /// 获取普通分页
        /// </summary>
        /// <param name="currentPageIndex">当前页</param>
        /// <param name="pageSize">每页显示的记录个数</param>
        /// <param name="recordCount"></param>
        /// <returns></returns>
        private static MvcHtmlString GetNormalPage(HtmlHelper helper, int currentPageIndex, int pageSize, int recordCount, PageMode mode)
        {
            if (recordCount == 0) return EmptyPager();
            int pageCount = (recordCount % pageSize == 0 ? recordCount / pageSize : recordCount / pageSize + 1);
            StringBuilder url = new StringBuilder();
            var request = helper.ViewContext.HttpContext.Request;
            //取当前请求地址，并在后面加上?page=页号
            url.Append(request.Url.AbsolutePath + "?page={0}");
            //取当前请求的查询参数
            NameValueCollection collectionQueryString = request.QueryString;
            var keys = collectionQueryString.AllKeys;
            //除了page,controller和action之外的参数拼接到后面
            string[] excludeKeys = { "page", "controller", "action" };
            ////////foreach (var key in keys)
            ////////{
            ////////    if (!excludeKeys.Contains(key))
            ////////        url.AppendFormat("&{0}={1}", key, request[key]);
            ////////}
            RouteValueDictionary routevalues = new RouteValueDictionary();//路由值集合
            foreach (string key in collectionQueryString.AllKeys)
            {
                if (key != null)
                    routevalues.Add(key, collectionQueryString[key]);
            }

            //将通过Form提交过来的数据也拼接到后面，主要考虑用户数据查询条件后防止在分页过程中数据丢失，这里有一个安全问题就是将post的数据显示在链接地中
            ////////foreach (var formKey in request.Form.Keys)
            ////////{
            ////////    string key = formKey.ToString();
            ////////    //如果查询字符串中已经包含，则排除
            ////////    if (keys.Contains(key)) continue;
            ////////    //排除特定的关键字
            ////////    if (!excludeKeys.Contains(key))
            ////////        url.AppendFormat("&{0}={1}", key, (string)(request.Form[key]));
            ////////}
            foreach (string formKey in request.Form.Keys)
            {
                string key = formKey.ToString();
                //如果查询字符串中已经包含，则排除
                if (keys.Contains(key)) continue;
                routevalues.Add(key, request.Form[key]);
            }


            StringBuilder sb = new StringBuilder();
            if (currentPageIndex == 1)
                sb.Append("<li class='disabled'><a>首页</a></li>");
            else
            {
                string url1 = CreateUrl(helper, routevalues, 1);//string.Format(url.ToString(), 1);
                sb.AppendFormat("<li><a href='{0}'>首页</a></li>", url1);
            }
            if (currentPageIndex > 1)
            {
                string url1 = CreateUrl(helper, routevalues, currentPageIndex - 1);//string.Format(url.ToString(), currentPageIndex - 1);
                sb.AppendFormat("<li><a href='{0}'>上页</a></li>", url1);
            }
            else
                sb.Append("<li class='disabled'><a>上页</a></li>");
            if (mode == PageMode.Numeric)
                sb.Append(GetNumericPage(currentPageIndex, pageSize, recordCount, pageCount, url.ToString()));
            if (currentPageIndex < pageCount)
            {
                string url1 = CreateUrl(helper, routevalues, currentPageIndex + 1);// string.Format(url.ToString(), currentPageIndex + 1);
                sb.AppendFormat("<li><a href='{0}'>下页</a></li>", url1);
            }
            else
                sb.Append("<li class='disabled'><a>下页</a></li>");

            if (currentPageIndex == pageCount || pageCount == 0)
                sb.Append("<li class='disabled'><a>末页</a></li>");
            else
            {
                string url1 = CreateUrl(helper, routevalues, pageCount);//  string.Format(url.ToString(), pageCount);
                sb.AppendFormat("<li><a href='{0}'>末页</a></li>", url1);
            }
            if (pageCount > 3)
            {
                string pageInputId = string.Format("pageNumber{0}", Guid.NewGuid().ToString("N"));
                string url1 = CreateUrl(helper, routevalues, "_pageIndex_");// string.Format(url.ToString(), "_pageIndex_");
                sb.Append("<li><a href=\"javascript: var url = '" + url1 + "'; url=url.replace('_pageIndex_', $('#" + pageInputId + "').val()); window.location.href = url; \">转</a><input class='page-number-input' type='number' id='" + pageInputId + "' value='" + currentPageIndex.ToString() + "' onkeydown=\"javascript: if (window.event.keyCode == 13) { var url = '" + url1 + "'; url=url.replace('_pageIndex_', $('#" + pageInputId + "').val()); window.location.href = url; }\"/></li>");
            }
            sb.AppendFormat("<span class='text-right' style='display: block; float: left;height: 30px;line-height: 30px;padding-left: 20px;'>第{2}页/共{1}页, 总共{0}条记录</span>", recordCount, pageCount, Math.Min(currentPageIndex, pageCount));

            return MvcHtmlString.Create(sb.ToString());
        }
        /// <summary>
        /// 生成链接地址
        /// </summary>
        /// <param name="helper">HtmlHelper对象</param>
        /// <param name="routevalues">路由信息</param>
        /// <param name="pageNumber">页号</param>
        /// <returns></returns>
        private static string CreateUrl(HtmlHelper helper, RouteValueDictionary routevalues, int pageNumber)
        {
            return CreateUrl(helper, routevalues, pageNumber.ToString());
        }
        /// <summary>
        /// 生成链接地址
        /// </summary>
        /// <param name="helper">HtmlHelper对象</param>
        /// <param name="routevalues">路由信息</param>
        /// <param name="pageNumber">页数</param>
        /// <returns></returns>
        private static string CreateUrl(HtmlHelper helper, RouteValueDictionary routevalues, string pageNumber)
        {
            string pageparamname = "page";//页参数名
            routevalues[pageparamname] = pageNumber;
            return UrlHelper.GenerateUrl(null, null, null, routevalues, RouteTable.Routes, helper.ViewContext.RequestContext, true);
        }


        /// <summary>
        /// 获取数字分页
        /// </summary>
        /// <param name="currentPageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="recordCount"></param>
        /// <param name="pageCount"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        private static string GetNumericPage(int currentPageIndex, int pageSize, int recordCount, int pageCount, string url)
        {
            var start = Math.Max(1, currentPageIndex - 2 - Math.Max(0, currentPageIndex + 2 - pageCount));
            var end = Math.Min(pageCount, currentPageIndex + 2 - Math.Min(0, currentPageIndex - 2 - 1));
            StringBuilder sb = new StringBuilder();
            for (int i = start; i <= end; i++)
            {
                if (i == currentPageIndex)
                    sb.AppendFormat("<li class=\"active\"><a>{0}</a></li>", i);
                else
                {
                    string url1 = string.Format(url, i);
                    sb.AppendFormat("<li><a href='{0}'>{1}</a></li>", url1, i);
                }
            }
            return sb.ToString();
        }

        /// <summary>
        /// 获取普通分页
        /// </summary>
        /// <param name="currentPageIndex">当前页</param>
        /// <param name="pageSize">每页显示的记录个数</param>
        /// <param name="recordCount"></param>
        /// <returns></returns>
        private static MvcHtmlString AjaxGetNormalPage(HtmlHelper helper, int currentPageIndex, int pageSize, int recordCount, PageMode mode)
        {
            if (recordCount == 0) return EmptyPager();
            int pageCount = (recordCount % pageSize == 0 ? recordCount / pageSize : recordCount / pageSize + 1);
            StringBuilder url = new StringBuilder();
            var request = helper.ViewContext.HttpContext.Request;
            url.Append(request.Url.AbsolutePath + "?page={0}");
            NameValueCollection collectionQueryString = request.QueryString;
            var keys = collectionQueryString.AllKeys;
            foreach (var key in keys)
            {
                if (key.ToLower() != "page")
                    url.AppendFormat("&{0}={1}", key, request[key]);
            }
            string stringUrl = AjaxPager(url.ToString(), "");
            StringBuilder sb = new StringBuilder();
            if (currentPageIndex == 1)
                sb.Append("<li class='disabled'><a>首页</a></li>");
            else
            {
                string url1 = string.Format(stringUrl.ToString(), 1);
                sb.AppendFormat("<li><a href='{0}'>首页</a></li>", url1);
            }
            if (currentPageIndex > 1)
            {
                string url1 = string.Format(stringUrl.ToString(), currentPageIndex - 1);
                sb.AppendFormat("<li><a href='{0}'>上一页</a></li>", url1);
            }
            else
                sb.Append("<li class='disabled'><a>上一页</a></li>");
            if (mode == PageMode.Numeric)
                sb.Append(AjaxGetNumericPage(currentPageIndex, pageSize, recordCount, pageCount, stringUrl.ToString()));
            if (currentPageIndex < pageCount)
            {
                string url1 = string.Format(stringUrl.ToString(), currentPageIndex + 1);
                sb.AppendFormat("<li><a href='{0}'>下一页</a></li>", url1);
            }
            else
                sb.Append("<li class='disabled'><a>下一页</a></li>");

            if (currentPageIndex == pageCount || pageCount == 0)
                sb.Append("<li class='disabled'><a>末页</a></li>");
            else
            {
                string url1 = string.Format(stringUrl.ToString(), pageCount);
                sb.AppendFormat("<li><a href='{0}'>末页</a></li>", url1);
            }
            sb.AppendFormat("<p class='text-right'style='display: block; float: left;height: 30px;line-height: 30px;padding-left: 20px;'>第{2}页/共{1}页, 总共{0}条记录</p>", recordCount, pageCount, Math.Min(currentPageIndex, pageCount));
            sb.Append(AjaxPagerFunction());
            return MvcHtmlString.Create(sb.ToString());
        }

        /// <summary>
        /// 获取数字分页
        /// </summary>
        /// <param name="currentPageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="recordCount"></param>
        /// <param name="pageCount"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        private static string AjaxGetNumericPage(int currentPageIndex, int pageSize, int recordCount, int pageCount, string url)
        {
            var start = Math.Max(1, currentPageIndex - 2 - Math.Max(0, currentPageIndex + 2 - pageCount));
            var end = Math.Min(pageCount, currentPageIndex + 2 - Math.Min(0, currentPageIndex - 2 - 1));
            StringBuilder sb = new StringBuilder();
            for (int i = start; i <= end; i++)
            {
                if (i == currentPageIndex)
                    sb.AppendFormat("<li class=\"active\"><a>{0}</a></li>", i);
                else
                {
                    string url1 = string.Format(url, i);
                    sb.AppendFormat("<li><a href='{0}'>{1}</a></li>", url1, i);
                }
            }
            return sb.ToString();
        }

        private static string AjaxPagerFunction()
        {
            string javaScript = @"
<script type='text / javascript'>
    function loadPage(url, tag)
    {
        $.get(url, { }, function(data) {
            $('#' + tag.html(data));
            })
    }
</script>";
            return javaScript;
        }
        private static string AjaxPager(string url, string parentContainer)
        {
            return string.Format("javascript:loadPage(\"{0}\",\"{1}\")");
        }

        /// <summary>
        /// 创建提交文件的Form
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <returns></returns>
        public static MvcForm BeginFilePostForm(this HtmlHelper htmlHelper)
        {
            string actionName = htmlHelper.ViewContext.RouteData.GetRequiredString("action");
            string controllerName = htmlHelper.ViewContext.RouteData.GetRequiredString("controller");
            MvcForm mvcForm = htmlHelper.BeginForm(actionName, controllerName, FormMethod.Post, new { enctype = "multipart/form-data" });
            return mvcForm;
        }
    }
    /// <summary>
    /// 分页模式
    /// </summary>
    public enum PageMode
    {
        /// <summary>
        /// 普通分页模式
        /// </summary>
        Normal,
        /// <summary>
        /// 普通分页加数字分页
        /// </summary>
        Numeric
    }
}